package com.xinyue.auto.reader;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;

import com.xinyue.auto.annotation.Create;
import com.xinyue.auto.annotation.ListClear;
import com.xinyue.auto.annotation.SetBoolean;
import com.xinyue.auto.annotation.SetNull;
import com.xinyue.auto.annotation.StringReset;

/**
 * 注入属性值
 */
public class Inject {
	
	/**
	 * 给对象属性注入数据
	 * @param map 数据集
	 * @param obj 被注入数据的对象（已创建）
	 * @throws Exception
	 */
	public static <T> void injectValue(T obj) throws Exception {
		Class<?> clazz = obj.getClass();
		
		while(clazz != null) {
			//如果clazz对象为Process对象，则停止搜索
			if(clazz.equals(Process.class)) {
				//跳出循环
				break;
			}
			
			//获取当前对象内部定义的全局属性
			Field[] fields = clazz.getDeclaredFields();
			if(fields != null && fields.length > 0) {
				for (Field fd: fields) {
					//获取该属性定义的所有注解
					Annotation[] anns = fd.getAnnotations();
					//如果定义了注解，并且只有一个注解时，进行处理
					if(anns != null && anns.length == 1) {
						annProcess(obj, anns[0], fd);
					}
				}
			}
			
			//获取当前对象的父类
			clazz = clazz.getSuperclass();
		}
	}
	
	/**
	 * 对属性的注解类型做预处理
	 * @param obj
	 * @param ann
	 * @param fd
	 */
	private static <T> void annProcess(T obj, Annotation ann, Field fd) {
		try {
			//注解类型
			Class<?> type = ann.annotationType();
			//设置私有属性可访问
			fd.setAccessible(true);
		
			if(type.equals(ListClear.class)) {
				List<?> list = (List<?>) fd.get(obj);
				//如果list有数据，则清空数据
				if(list != null && list.size() > 0) {
					list.clear();
				}
			}else if(type.equals(SetNull.class)) {
				//将对象的数据设置为null
					fd.set(obj, null);
			}else if(type.equals(SetBoolean.class)) {
				//获取注解
				SetBoolean annt = fd.getAnnotation(SetBoolean.class);
				//将对象的数据设置为默认值
				fd.set(obj, annt.value());
			}else if(type.equals(Create.class)) {
				//获取注解
				Create annt = fd.getAnnotation(Create.class);
				//将对象的数据设置为默认值
				fd.set(obj, annt.value().newInstance());
			}else if(type.equals(StringReset.class)) {
				//获取注解
				StringReset annt = fd.getAnnotation(StringReset.class);
				//将对象的数据设置为默认值
				fd.set(obj, annt.value());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}